import pygame, sys, os
from pygame.locals import *
from ghost import *
from map import *
from jiong import *
from player import *

class Game(object):
    STATE_GAMING = 1
    STATE_DEAD = 2
    STATE_WIN = 3
    STATE_DONE = 4
    
    
    __window_size = (800, 600)
    __caption = 'Jiong World'
    __action_key = [K_LEFT, K_RIGHT, K_SPACE]
    __state_max = 100    
    
    def __init__(self):
        if sys.platform in ("win32", "win64"):
            os.environ["SDL_VIDEO_CENTERED"] = "1"
        pygame.init()
        self.__window = pygame.display.set_mode(Game.__window_size)
        pygame.display.set_caption(Game.__caption)
        self.__clock = pygame.time.Clock()
        self.__level = 1
        self.__state = Game.STATE_GAMING
        self.__font = pygame.font.SysFont("simsun&nsimsun", 100, True)
        self.__statetick = 0
    
    def start(self):
        # program loop
        while self.__state == Game.STATE_GAMING:
            # init map
            map = Map(level[self.__level], Game.__window_size)
            map_window = pygame.Surface(map.get_size())
            # init sprite and group
            player = map.get_player()
            render = pygame.sprite.RenderUpdates()
            render.add(player, map.get_ghost())
            rule = pygame.sprite.Group()
            rule.add(player, map.get_ghost())
            all = pygame.sprite.Group()
            all.add(player, map.get_ghost(), map.get_bound(), map.get_block())
            # game loop
            while self.__state != Game.STATE_DONE:
                # keep fps
                self.__clock.tick(50)
                # draw window
                pygame.display.update() # why? for the __draw_result()
                map_window.blit(map.get_map(), (0, 0))
                render.draw(map_window)
                self.__window.blit(map_window, (0, 0), map.get_view())
                # sys
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        sys.exit()
                if self.__state == Game.STATE_DEAD:
                    self.__draw_result(False)
                    self.__statetick += 1
                    if self.__statetick >= Game.__state_max:
                        self.__state = Game.STATE_GAMING
                        self.__statetick = 0
                        break
                elif self.__state == Game.STATE_WIN:
                    self.__draw_result(True)
                    self.__statetick += 1
                    if self.__statetick >= Game.__state_max:
                        self.__state = Game.STATE_GAMING
                        self.__statetick = 0
                        break
                elif self.__state == Game.STATE_GAMING:
                    # update sprite action and frame
                    rule.update()
                    for spr in rule:
                        self.__game_rule(spr, spr.get_coll())
                    # update map view center
                    map.center_view(player.rect.center)
                    # get event                        
                    key = pygame.key.get_pressed()
                    for keyname in self.__action_key:
                        if key[keyname]: 
                            player.action(keyname)        

    def __draw_result(self, result):
        if result:
            font = self.__font.render(u"Game \u56e7 Winer!", 1, (100, 255, 100))
        else:
            font = self.__font.render(u"Game \u56e7 Over!", 1, (255, 100, 100))
        rect = font.get_rect()
        left = (self.__window_size[0] - rect.width) / 2
        top = (self.__window_size[1] - rect.height) / 2
        self.__window.blit(font, (left, top))
            
    def __game_rule(self, spr, coll):
        for item in coll:
            if (isinstance(spr, Player) and isinstance(item[0], Ghost)) \
            or (isinstance(spr, Ghost) and isinstance(item[0], Player)):
                self.__state = Game.STATE_DEAD
            elif isinstance(spr, Player) and isinstance(item[0], Bound):
                if item[1] == Jiong.TOP:
                    self.__state = Game.STATE_DEAD
                elif item[1] == Jiong.LEFT:
                    self.__state = Game.STATE_WIN
























